//*****************************-》 增强版循环列表 《-****************************
//author: 优化自UICircularScrollView
//优化点：
// 1. 改进对象池机制，避免不必要的实例化与销毁
// 2. 修复资源释放问题，防止内存泄漏
// 3. 优化布局计算逻辑，特别是在多行情况下
// 4. 完善边界条件处理
// 5. 提高滚动性能
// 6. 修复箭头指示逻辑
// 7. 增加列表项动画效果

//初始化:
//      Init(callBackFunc)
//刷新整个列表（首次调用和数量变化时调用）:
//      ShowList(int = 数量)
//刷新单个项:
//      UpdateCell(int = 索引)
//刷新列表数据(无数量变化时调用):
//      UpdateList()
//回调:
//Func(GameObject = Cell, int = Index)  //刷新列表

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System;
using UnityEngine.EventSystems;

namespace CircularScrollView
{
    // 动画管理器 - 用于统一管理列表项动画
    public class AnimationManager
    {
        // 动画类型
        public enum AnimationType
        {
            FadeIn,         // 淡入动画
            SlideIn,        // 滑入动画
            Scale,          // 缩放动画
            Combined,       // 组合动画（淡入+滑入）
            Custom          // 自定义动画
        }

        // 动画参数
        public class AnimationParams
        {
            public AnimationType type = AnimationType.Combined;  // 动画类型
            public float duration = 0.3f;                        // 动画持续时间
            public float delay = 0.05f;                          // 每项延迟时间
            public bool onlyFirstTime = true;                    // 是否仅首次显示播放
            public float fadeStartAlpha = 0f;                    // 初始透明度
            public float fadeEndAlpha = 1f;                      // 目标透明度
            public float slideOffset = 100f;                     // 滑动偏移距离
            public Vector3 scaleFrom = new Vector3(0.8f, 0.8f, 1f); // 初始缩放
            public Vector3 scaleTo = Vector3.one;                // 目标缩放
            public AnimationCurve curve = null;                  // 自定义动画曲线

            // 构造具有默认值的动画参数
            public AnimationParams(AnimationType animType = AnimationType.Combined)
            {
                type = animType;
                // 创建默认缓动曲线
                curve = AnimationCurve.EaseInOut(0, 0, 1, 1);
            }
        }

        // 动画状态
        private class AnimationState
        {
            public GameObject target;              // 动画目标对象
            public RectTransform rectTransform;    // 目标的RectTransform
            public CanvasGroup canvasGroup;        // 目标的CanvasGroup
            public Vector2 basePosition;           // 基础位置（滚动位置）
            public Vector2 animPosition;           // 动画位置（动画偏移）
            public Vector2 originalPosition;       // 原始起始位置
            public Vector2 targetPosition;         // 目标结束位置
            public Vector3 originalScale;          // 原始缩放
            public Vector3 targetScale;            // 目标缩放
            public float originalAlpha;            // 原始透明度
            public float targetAlpha;              // 目标透明度
            public float startTime;                // 动画开始时间
            public float duration;                 // 动画持续时间
            public bool isPlaying;                 // 是否正在播放中
            public int dataIndex;                  // 数据索引
            public AnimationCurve curve;           // 动画曲线
        }

        private EnhancedUICircularScrollView m_Owner;        // 所属的循环列表
        private Dictionary<int, AnimationState> m_ActiveAnimations; // 当前活动的动画
        private HashSet<int> m_AnimatedIndices;              // 已播放过动画的索引
        private AnimationParams m_DefaultParams;             // 默认动画参数
        private MonoBehaviour m_CoroutineRunner;             // 协程运行器
        private Coroutine m_UpdateCoroutine;                 // 动画更新协程
        private bool m_IsInitialized = false;                // 是否已初始化

        // 构造函数
        public AnimationManager(EnhancedUICircularScrollView owner)
        {
            m_Owner = owner;
            m_CoroutineRunner = owner;
            m_ActiveAnimations = new Dictionary<int, AnimationState>();
            m_AnimatedIndices = new HashSet<int>();
            m_DefaultParams = new AnimationParams();
            m_IsInitialized = true;
        }

        // 初始化
        public void Initialize(AnimationParams defaultParams = null)
        {
            if (defaultParams != null)
            {
                m_DefaultParams = defaultParams;
            }
            m_ActiveAnimations.Clear();
            m_IsInitialized = true;
        }

        // 释放资源
        public void Dispose()
        {
            StopAllAnimations();
            m_ActiveAnimations.Clear();
            m_AnimatedIndices.Clear();
            m_IsInitialized = false;
        }

        // 设置默认动画参数
        public void SetDefaultParams(AnimationParams parameters)
        {
            if (parameters != null)
            {
                m_DefaultParams = parameters;
            }
        }

        // 重置动画状态（清除已播放记录）
        public void ResetAnimationState()
        {
            m_AnimatedIndices.Clear();
        }

        // 应用动画初始状态
        public void PrepareItemForAnimation(GameObject item, int dataIndex, Vector2 basePosition)
        {
            if (!m_IsInitialized || item == null || !m_Owner.m_EnableItemAnimation)
                return;

            // 检查是否需要播放动画
            if (m_Owner.m_OnlyAnimateFirstTime && m_AnimatedIndices.Contains(dataIndex))
                return;

            try
            {
                // 获取或添加必要组件
                RectTransform rectTrans = item.GetComponent<RectTransform>();
                CanvasGroup canvasGroup = item.GetComponent<CanvasGroup>();
                if (canvasGroup == null)
                {
                    canvasGroup = item.AddComponent<CanvasGroup>();
                }

                // 根据动画类型设置初始状态
                switch (m_DefaultParams.type)
                {
                    case AnimationType.FadeIn:
                        canvasGroup.alpha = m_DefaultParams.fadeStartAlpha;
                        break;

                    case AnimationType.SlideIn:
                        Vector2 slideOffset = m_Owner.Direction == e_Direction.Vertical ?
                            new Vector2(m_DefaultParams.slideOffset, 0) :
                            new Vector2(0, m_DefaultParams.slideOffset);
                        rectTrans.anchoredPosition = basePosition + slideOffset;
                        break;

                    case AnimationType.Scale:
                        rectTrans.localScale = m_DefaultParams.scaleFrom;
                        break;

                    case AnimationType.Combined:
                    default:
                        canvasGroup.alpha = m_DefaultParams.fadeStartAlpha;
                        Vector2 offset = m_Owner.Direction == e_Direction.Vertical ?
                            new Vector2(m_DefaultParams.slideOffset, 0) :
                            new Vector2(0, m_DefaultParams.slideOffset);
                        rectTrans.anchoredPosition = basePosition + offset;
                        break;
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"准备动画时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 播放单个项目的动画
        public void PlayItemAnimation(GameObject item, int dataIndex, Vector2 basePosition, float delay = 0f)
        {
            if (!m_IsInitialized || item == null || !m_Owner.m_EnableItemAnimation)
                return;

            // 检查是否需要播放动画
            if (m_Owner.m_OnlyAnimateFirstTime && m_AnimatedIndices.Contains(dataIndex))
                return;

            try
            {
                // 获取必要组件
                RectTransform rectTrans = item.GetComponent<RectTransform>();
                CanvasGroup canvasGroup = item.GetComponent<CanvasGroup>();
                
                if (rectTrans == null) return;
                if (canvasGroup == null && (m_DefaultParams.type == AnimationType.FadeIn || 
                                          m_DefaultParams.type == AnimationType.Combined))
                {
                    canvasGroup = item.AddComponent<CanvasGroup>();
                }

                // 创建动画状态
                AnimationState state = new AnimationState
                {
                    target = item,
                    rectTransform = rectTrans,
                    canvasGroup = canvasGroup,
                    basePosition = basePosition,
                    dataIndex = dataIndex,
                    startTime = Time.time + delay,
                    duration = m_DefaultParams.duration,
                    isPlaying = true,
                    curve = m_DefaultParams.curve
                };

                // 根据动画类型设置初始状态和目标状态
                switch (m_DefaultParams.type)
                {
                    case AnimationType.FadeIn:
                        state.originalAlpha = m_DefaultParams.fadeStartAlpha;
                        state.targetAlpha = m_DefaultParams.fadeEndAlpha;
                        state.animPosition = Vector2.zero;
                        break;

                    case AnimationType.SlideIn:
                        Vector2 slideOffset = m_Owner.Direction == e_Direction.Vertical ?
                            new Vector2(m_DefaultParams.slideOffset, 0) :
                            new Vector2(0, m_DefaultParams.slideOffset);
                        state.originalPosition = basePosition + slideOffset;
                        state.targetPosition = basePosition;
                        state.animPosition = slideOffset;
                        break;

                    case AnimationType.Scale:
                        state.originalScale = m_DefaultParams.scaleFrom;
                        state.targetScale = m_DefaultParams.scaleTo;
                        state.animPosition = Vector2.zero;
                        break;

                    case AnimationType.Combined:
                    default:
                        state.originalAlpha = m_DefaultParams.fadeStartAlpha;
                        state.targetAlpha = m_DefaultParams.fadeEndAlpha;
                        Vector2 offset = m_Owner.Direction == e_Direction.Vertical ?
                            new Vector2(m_DefaultParams.slideOffset, 0) :
                            new Vector2(0, m_DefaultParams.slideOffset);
                        state.originalPosition = basePosition + offset;
                        state.targetPosition = basePosition;
                        state.animPosition = offset;
                        break;
                }

                // 应用初始状态
                ApplyAnimationState(state, 0f);

                // 添加到活动动画列表
                if (m_ActiveAnimations.ContainsKey(dataIndex))
                {
                    m_ActiveAnimations[dataIndex] = state;
                }
                else
                {
                    m_ActiveAnimations.Add(dataIndex, state);
                }

                // 标记为已播放动画
                if (m_Owner.m_OnlyAnimateFirstTime)
                {
                    m_AnimatedIndices.Add(dataIndex);
                }

                // 确保更新协程在运行
                EnsureUpdateCoroutineRunning();
            }
            catch (Exception ex)
            {
                Debug.LogError($"启动动画时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 批量播放动画
        public void PlayItemsAnimation(List<KeyValuePair<GameObject, int>> itemsToAnimate, List<Vector2> basePositions)
        {
            if (!m_IsInitialized || itemsToAnimate == null || itemsToAnimate.Count == 0 || !m_Owner.m_EnableItemAnimation)
                return;

            try
            {
                // 按索引排序，确保动画按顺序播放
                itemsToAnimate.Sort((a, b) => a.Value.CompareTo(b.Value));

                // 依次播放动画，应用延迟
                for (int i = 0; i < itemsToAnimate.Count; i++)
                {
                    if (itemsToAnimate[i].Key == null) continue;

                    float delay = i * m_DefaultParams.delay;
                    Vector2 basePos = (i < basePositions.Count) ? basePositions[i] : Vector2.zero;
                    PlayItemAnimation(itemsToAnimate[i].Key, itemsToAnimate[i].Value, basePos, delay);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"批量播放动画时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 更新项目的基础位置（在滑动时调用）
        public void UpdateItemBasePosition(int dataIndex, Vector2 newBasePosition)
        {
            if (!m_IsInitialized)
                return;

            if (m_ActiveAnimations.TryGetValue(dataIndex, out AnimationState state))
            {
                state.basePosition = newBasePosition;
                // 更新目标位置
                state.targetPosition = newBasePosition;
                // 如果动画已接近完成，直接设置为完成状态，避免闪烁
                if (GetAnimationProgress(state) > 0.95f)
                {
                    FinishItemAnimation(dataIndex);
                }
                else
                {
                    // 应用最新的动画状态
                    ApplyAnimationState(state, GetAnimationProgress(state));
                }
            }
        }

        // 停止单个项目的动画
        public void StopItemAnimation(int dataIndex, bool jumpToEnd = true)
        {
            if (!m_IsInitialized)
                return;

            if (m_ActiveAnimations.TryGetValue(dataIndex, out AnimationState state))
            {
                if (jumpToEnd)
                {
                    ApplyAnimationState(state, 1.0f);
                }
                m_ActiveAnimations.Remove(dataIndex);
            }
        }

        // 停止所有动画
        public void StopAllAnimations(bool jumpToEnd = true)
        {
            if (!m_IsInitialized)
                return;

            if (jumpToEnd)
            {
                foreach (var state in m_ActiveAnimations.Values)
                {
                    ApplyAnimationState(state, 1.0f);
                }
            }

            m_ActiveAnimations.Clear();

            if (m_UpdateCoroutine != null)
            {
                m_CoroutineRunner.StopCoroutine(m_UpdateCoroutine);
                m_UpdateCoroutine = null;
            }
        }

        // 完成单个项目的动画（跳到结束状态）
        private void FinishItemAnimation(int dataIndex)
        {
            if (m_ActiveAnimations.TryGetValue(dataIndex, out AnimationState state))
            {
                ApplyAnimationState(state, 1.0f);
                m_ActiveAnimations.Remove(dataIndex);
            }
        }

        // 应用动画状态
        private void ApplyAnimationState(AnimationState state, float progress)
        {
            if (state == null || state.target == null || !state.target.activeInHierarchy)
                return;

            try
            {
                // 应用缓动曲线
                float easedProgress = progress;
                if (state.curve != null)
                {
                    easedProgress = state.curve.Evaluate(progress);
                }

                // 根据动画类型应用效果
                switch (m_DefaultParams.type)
                {
                    case AnimationType.FadeIn:
                        if (state.canvasGroup != null)
                        {
                            state.canvasGroup.alpha = Mathf.Lerp(state.originalAlpha, state.targetAlpha, easedProgress);
                        }
                        // 位置直接使用基础位置
                        state.rectTransform.anchoredPosition = state.basePosition;
                        break;

                    case AnimationType.SlideIn:
                        // 位置使用基础位置加上动画位置的插值
                        Vector2 animOffset = Vector2.Lerp(state.animPosition, Vector2.zero, easedProgress);
                        state.rectTransform.anchoredPosition = state.basePosition + animOffset;
                        break;

                    case AnimationType.Scale:
                        state.rectTransform.localScale = Vector3.Lerp(state.originalScale, state.targetScale, easedProgress);
                        // 位置直接使用基础位置
                        state.rectTransform.anchoredPosition = state.basePosition;
                        break;

                    case AnimationType.Combined:
                    default:
                        if (state.canvasGroup != null)
                        {
                            state.canvasGroup.alpha = Mathf.Lerp(state.originalAlpha, state.targetAlpha, easedProgress);
                        }
                        // 位置使用基础位置加上动画位置的插值
                        Vector2 offset = Vector2.Lerp(state.animPosition, Vector2.zero, easedProgress);
                        state.rectTransform.anchoredPosition = state.basePosition + offset;
                        break;
                }

                // 应用滑动动画
                if (state.rectTransform != null)
                {
                    Vector2 slideOffset = m_Owner.Direction == e_Direction.Vertical ?
                        new Vector2(m_DefaultParams.slideOffset * (1 - progress), 0) :
                        new Vector2(0, m_DefaultParams.slideOffset * (1 - progress));

                    state.rectTransform.anchoredPosition = state.basePosition + slideOffset;
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"应用动画状态时出错: {ex.Message}\n{ex.StackTrace}");
                m_ActiveAnimations.Remove(state.dataIndex);
            }
        }

        // 获取动画进度
        private float GetAnimationProgress(AnimationState state)
        {
            if (state == null)
                return 1.0f;

            float elapsed = Time.time - state.startTime;
            return Mathf.Clamp01(elapsed / state.duration);
        }

        // 确保更新协程在运行
        private void EnsureUpdateCoroutineRunning()
        {
            if (m_UpdateCoroutine == null)
            {
                m_UpdateCoroutine = m_CoroutineRunner.StartCoroutine(UpdateAnimations());
            }
        }

        // 动画更新协程
        private System.Collections.IEnumerator UpdateAnimations()
        {
            while (m_ActiveAnimations.Count > 0)
            {
                List<int> finishedAnimations = new List<int>();

                foreach (var kvp in m_ActiveAnimations)
                {
                    AnimationState state = kvp.Value;
                    if (state.target == null || !state.target.activeInHierarchy)
                    {
                        finishedAnimations.Add(kvp.Key);
                        continue;
                    }

                    // 检查是否到了开始时间
                    if (Time.time >= state.startTime)
                    {
                        float progress = GetAnimationProgress(state);
                        ApplyAnimationState(state, progress);

                        // 检查是否完成
                        if (progress >= 1.0f)
                        {
                            finishedAnimations.Add(kvp.Key);
                        }
                    }
                }

                // 移除已完成的动画
                foreach (int index in finishedAnimations)
                {
                    m_ActiveAnimations.Remove(index);
                }

                yield return null;
            }

            m_UpdateCoroutine = null;
        }
    }

    public class EnhancedUICircularScrollView : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
    {
        [Header("滚动指示箭头")]
        [Tooltip("指向列表开始位置的箭头，用于提示用户可以向上/左滚动")]
        public GameObject m_PointingFirstArrow; // 起始位置箭头
        [Tooltip("指向列表结束位置的箭头，用于提示用户可以向下/右滚动")]
        public GameObject m_PointingEndArrow;   // 结束位置箭头

        [Header("基本设置")]
        public e_Direction m_Direction = e_Direction.Horizontal; // 滚动方向
        
        // 提供只读访问
        public e_Direction Direction { get { return m_Direction; } }
        
        [Tooltip("是否显示滚动提示箭头，当内容超出可视区域时箭头会自动显示")]
        public bool m_IsShowArrow = true;                       // 是否显示箭头
        [Tooltip("每行/列显示的项目数量，垂直滚动时为列数，水平滚动时为行数")]
        public int m_Row = 1;                                   // 每行/列显示的数量
        [Tooltip("项目之间的间距，单位为像素")]
        public float m_Spacing = 0f;                            // 间距
        [Tooltip("列表内容的内边距，用于控制列表项与边缘的距离")]
        public RectOffset m_Padding = new RectOffset();         // 内边距
        [Tooltip("列表项目的模板对象，用于实例化显示的项目")]
        public GameObject m_CellGameObject;                      // 项目模板

        [Header("性能优化")]
        [Tooltip("预先创建的对象数量，用于减少运行时的实例化开销")]
        [SerializeField] private int m_PoolPreloadCount = 10;    // 预加载的Cell数量
        [Tooltip("预加载缓冲区大小，决定在可视区域外预先加载的范围，单位为像素")]
        [SerializeField] private float m_PreloadBufferZone = 0f; // 预加载缓冲区大小，默认为0
        [Tooltip("极致缓存模式：仅显示视口内的项目，可提高性能但可能影响滚动流畅度")]
        [SerializeField] private bool m_ExtremeCacheMode = true; // 默认启用极致缓存模式
        [Tooltip("对象池最大容量：-1为无限制，0为不使用对象池，大于0为限制数量")]
        [SerializeField] private int m_MaxPoolSize = -1;         // 对象池最大大小，-1为无限制，0为不使用对象池，>0为限制数量
        
        [Header("缓存区控制")]
        [Tooltip("前向缓存数量：可视区域前方(上/左)需要预先加载的行/列数")]
        [SerializeField] private int m_BeforeCacheCount = 0;      // 前向缓存数量(上/左)，默认为0
        [Tooltip("后向缓存数量：可视区域后方(下/右)需要预先加载的行/列数")]
        [SerializeField] private int m_AfterCacheCount = 0;      // 后向缓存数量(下/右)，默认为0
        [Tooltip("是否使用数量模式控制缓存区：基于行/列数量而非像素距离")]
        [SerializeField] private bool m_UseCacheCountMode = false; // 是否使用数量模式控制缓存区

        [Header("动画设置")]
        [Tooltip("是否启用项目进入动画：项目进入可视区域时播放淡入和位移动画")]
        public bool m_EnableItemAnimation = true;               // 是否启用项目动画
        [Tooltip("是否只在首次填充列表时执行动画，滚动时不再播放动画")]
        public bool m_OnlyAnimateFirstTime = true;              // 是否只在首次填充时执行动画
        [Tooltip("项目动画的持续时间，单位为秒")]
        public float m_AnimationDuration = 0.3f;                // 动画持续时间
        [Tooltip("每项动画的延迟时间，实现项目依次进入的效果，单位为秒")]
        public float m_AnimationOffset = 0.05f;                 // 每项动画的延迟时间

        // 已经播放过动画的项目索引
        protected HashSet<int> m_AnimatedItems = new HashSet<int>();
        // 记录当前处于真实可见区域的项目索引
        protected HashSet<int> m_RealVisibleItems = new HashSet<int>();

        // 回调函数
        protected Action<GameObject, int> m_FuncCallBackFunc;       // 更新Cell的回调

        // 布局相关
        protected RectTransform m_RectTransform;
        protected float m_ViewportWidth;
        protected float m_ViewportHeight;
        protected float m_ContentWidth;
        protected float m_ContentHeight;
        protected float m_CellWidth;
        protected float m_CellHeight;

        // 组件引用
        protected GameObject m_Content;
        protected RectTransform m_ViewportRectTransform;
        protected RectTransform m_ContentRectTransform;
        protected ScrollRect m_ScrollRect;

        // 状态标记
        protected bool m_IsInitialized = false;
        protected bool m_IsClearList = false;
        
        // 列表项信息
        protected struct CellInfo
        {
            public Vector3 position;
            public GameObject obj;
            public int dataIndex;  // 数据索引
            public bool isVisible; // 是否可见
        }
        protected CellInfo[] m_CellInfos;
        
        // 显示相关
        protected int m_TotalCount = 0;
        protected int m_FirstVisibleIndex = -1;
        protected int m_LastVisibleIndex = -1;

        // 对象池
        protected ObjectPool m_CellPool;

        // 动画管理器
        protected AnimationManager m_AnimationManager;

        #region 对象池实现
        protected class ObjectPool
        {
            // 使用List代替Stack，因为List在大量对象进出池时性能更好
            private List<GameObject> m_Pool = new List<GameObject>();
            private GameObject m_Template;
            private Transform m_Parent;
            private int m_Count = 0;
            private int m_MaxSize = -1; // 对象池最大大小，-1表示不限制

            public ObjectPool(GameObject template, Transform parent, int preloadCount = 0, int maxSize = -1)
            {
                m_Template = template;
                m_Parent = parent;
                m_MaxSize = maxSize;
                
                if (m_Template != null)
                    m_Template.SetActive(false);
                else
                    return;

                // 预加载对象
                for (int i = 0; i < preloadCount && (maxSize < 0 || i < maxSize); i++)
                {
                    GameObject obj = CreateNewObject();
                    if (obj != null)
                        RecycleObject(obj);
                }
            }

            public GameObject GetObject()
            {
                GameObject obj;
                
                int count = m_Pool.Count;
                if (count > 0)
                {
                    // 从列表末尾取对象，避免移动元素，提高性能
                    obj = m_Pool[count - 1];
                    m_Pool.RemoveAt(count - 1);
                }
                else
                {
                    obj = CreateNewObject();
                }
                
                if (obj != null)
                    obj.SetActive(true);
                    
                return obj;
            }

            public void RecycleObject(GameObject obj)
            {
                if (obj == null) return;
                
                // 在回收前重置透明度
                CanvasGroup canvasGroup = obj.GetComponent<CanvasGroup>();
                if (canvasGroup != null)
                {
                    canvasGroup.alpha = 1.0f; // 确保透明度被重置为1.0
                }
                
                // 检查对象池是否已达到最大大小限制
                if (m_MaxSize >= 0 && m_Pool.Count >= m_MaxSize)
                {
                    // 超过最大大小，直接销毁对象
                    GameObject.Destroy(obj);
                    return;
                }
                
                obj.SetActive(false);
                
                // 避免重复加入池中
                if (!m_Pool.Contains(obj))
                    m_Pool.Add(obj);
            }

            public void Clear()
            {
                foreach (GameObject obj in m_Pool)
                {
                    if (obj != null)
                        GameObject.Destroy(obj);
                }
                m_Pool.Clear();
            }
            
            // 设置对象池的最大大小
            public void SetMaxSize(int maxSize)
            {
                m_MaxSize = maxSize;
                
                // 如果当前池中的对象超过新的最大值，则销毁多余的对象
                if (m_MaxSize >= 0)
                {
                    while (m_Pool.Count > m_MaxSize)
                    {
                        int lastIndex = m_Pool.Count - 1;
                        GameObject obj = m_Pool[lastIndex];
                        m_Pool.RemoveAt(lastIndex);
                        
                        if (obj != null)
                            GameObject.Destroy(obj);
                    }
                }
            }

            public int Count
            {
                get { return m_Count; }
            }
            
            public int PooledCount
            {
                get { return m_Pool.Count; }
            }

            private GameObject CreateNewObject()
            {
                if (m_Template == null || m_Parent == null) return null;
                
                GameObject obj = GameObject.Instantiate(m_Template, m_Parent);
                if (obj != null)
                {
                    obj.name = "Cell_" + m_Count++;
                }
                return obj;
            }
        }
        #endregion

        #region 初始化方法
        public virtual void Init(Action<GameObject, int> callBack)
        {
            // 释放旧资源
            DisposeAll();

            // 设置回调
            m_FuncCallBackFunc = callBack;

            // 避免重复初始化
            if (m_IsInitialized)
                return;

            // 获取组件引用
            m_RectTransform = GetComponent<RectTransform>();
            m_ScrollRect = GetComponent<ScrollRect>();
            m_Content = m_ScrollRect.content.gameObject;
            
            if (m_ScrollRect.viewport)
                m_ViewportRectTransform = m_ScrollRect.viewport.GetComponent<RectTransform>();
            else
                m_ViewportRectTransform = m_RectTransform;

            // 检查模板Cell
            if (m_CellGameObject == null && m_Content.transform.childCount > 0)
            {
                m_CellGameObject = m_Content.transform.GetChild(0).gameObject;
            }

            if (m_CellGameObject == null)
            {
                Debug.LogError("初始化对象池失败: Cell模板为空");
                return;
            }

            // 设置模板Cell属性
            RectTransform cellRectTrans = m_CellGameObject.GetComponent<RectTransform>();
            
            CheckCellAnchor(cellRectTrans);
            cellRectTrans.anchoredPosition = Vector2.zero;

            // 记录尺寸信息
            m_CellWidth = cellRectTrans.rect.width;
            m_CellHeight = cellRectTrans.rect.height;

            Rect viewportRect = m_ViewportRectTransform.rect;
            m_ViewportWidth = viewportRect.width;
            m_ViewportHeight = viewportRect.height;

            // 自动检测并应用滚动方向
            if (m_ScrollRect != null)
            {
                // 检查是否需要修改方向
                bool wasHorizontal = Direction == e_Direction.Horizontal;
                
                // 如果 vertical 为 true，则设置为垂直滚动方向
                // 如果 horizontal 为 true，则设置为水平滚动方向
                // 优先使用垂直方向（如果两者都启用）
                if (m_ScrollRect.vertical)
                {
                    m_Direction = e_Direction.Vertical;
                }
                else if (m_ScrollRect.horizontal)
                {
                    m_Direction = e_Direction.Horizontal;
                }
            }

            // 设置Content属性
            m_ContentRectTransform = m_Content.GetComponent<RectTransform>();
            CheckContentAnchor(m_ContentRectTransform);

            // 初始化对象池
            if (m_CellGameObject != null)
            {
                m_CellPool = new ObjectPool(m_CellGameObject, m_Content.transform, m_PoolPreloadCount, m_MaxPoolSize);
            }
            else
            {
                Debug.LogError("初始化对象池失败: Cell模板为空");
                return;
            }

            // 添加滚动监听
            m_ScrollRect.onValueChanged.RemoveAllListeners();
            m_ScrollRect.onValueChanged.AddListener(ScrollRectListener);
            
            // 箭头监听
            if (m_IsShowArrow && (m_PointingFirstArrow != null || m_PointingEndArrow != null))
            {
                m_ScrollRect.onValueChanged.AddListener(OnScrollArrowUpdate);
                OnScrollArrowUpdate(Vector2.zero);
            }
            
            // 初始化动画管理器
            if (m_AnimationManager == null)
            {
                m_AnimationManager = new AnimationManager(this);
                
                // 配置默认动画参数
                AnimationManager.AnimationParams defaultParams = new AnimationManager.AnimationParams();
                defaultParams.duration = m_AnimationDuration;
                defaultParams.delay = m_AnimationOffset;
                defaultParams.onlyFirstTime = m_OnlyAnimateFirstTime;
                defaultParams.slideOffset = Direction == e_Direction.Vertical ? 
                                          Mathf.Min(100f, m_CellWidth * 0.25f) : 
                                          Mathf.Min(100f, m_CellHeight * 0.25f);
                m_AnimationManager.SetDefaultParams(defaultParams);
            }
            
            m_IsInitialized = true;
            
            // 立即重新应用布局以确保所有锚点设置生效
            Canvas.ForceUpdateCanvases();
        }

        // 检查锚点设置
        private void CheckContentAnchor(RectTransform rectTrans)
        {
            if (rectTrans == m_ContentRectTransform)
            {
                if (Direction == e_Direction.Vertical)
                {
                    // 垂直滚动时的Content锚点预设
                    rectTrans.anchorMin = new Vector2(0, 1);
                    rectTrans.anchorMax = new Vector2(1, 1);
                    rectTrans.pivot = new Vector2(0, 1);
                    // 确保设置锚点后位置正确
                    rectTrans.anchoredPosition = new Vector2(0, 0);
                }
                else
                {
                    // 水平滚动时的Content锚点预设
                    // 使用左上角锚点以便统一计算逻辑
                    rectTrans.anchorMin = new Vector2(0, 0);
                    rectTrans.anchorMax = new Vector2(0, 1);
                    rectTrans.pivot = new Vector2(0, 1);
                    // 确保设置锚点后位置正确
                    rectTrans.anchoredPosition = new Vector2(0, 0);
                    
                }
                return;
            }
        }
        // 检查锚点设置
        private void CheckCellAnchor(RectTransform rectTrans)
        {
            // Cell的锚点预设统一为左上角，便于计算位置
            rectTrans.anchorMin = new Vector2(0, 1);
            rectTrans.anchorMax = new Vector2(0, 1);
            rectTrans.pivot = new Vector2(0, 1);
        }
        #endregion

        #region 列表更新方法
        /// <summary>
        /// 更新整个列表内容（数量不变时使用）- 自动处理动画状态
        /// </summary>
        public virtual void UpdateList()
        {
            if (!m_IsInitialized || m_CellInfos == null)
                return;

            // 自动智能判断是否需要重置动画状态
            // 如果需要重复播放动画且不是仅首次播放，则重置动画状态
            if (m_EnableItemAnimation && !m_OnlyAnimateFirstTime)
            {
                m_AnimatedItems.Clear();
            }

            // 先更新所有可见项目的内容
            for (int i = 0; i < m_CellInfos.Length; i++)
            {
                CellInfo cellInfo = m_CellInfos[i];
                if (cellInfo.obj != null && cellInfo.isVisible)
                {
                    // 更新可见的Cell
                    UpdateCellContent(cellInfo.obj, i);
                }
            }
            
            // 然后刷新可见性，可能会触发新的动画
            UpdateVisibleCells();
        }

        /// <summary>
        /// 更新单个列表项内容
        /// </summary>
        /// <param name="index">要更新的项目索引(从1开始)</param>
        public virtual void UpdateCell(int index)
        {
            if (!m_IsInitialized || m_CellInfos == null || index <= 0 || index > m_CellInfos.Length)
                return;

            int arrayIndex = index - 1;
            CellInfo cellInfo = m_CellInfos[arrayIndex];
            
            if (cellInfo.obj != null && cellInfo.isVisible)
            {
                UpdateCellContent(cellInfo.obj, arrayIndex);
            }
        }

        /// <summary>
        /// 显示列表视图 - 主要外部接口
        /// 支持以下用法:
        /// 1. 初始化时调用 - 首次显示列表
        /// 2. 数据更新时调用 - 自动处理数量变化或内容刷新
        /// 3. 重复调用 - 智能优化，避免不必要的刷新
        /// </summary>
        /// <param name="itemCount">列表项总数</param>
        /// <param name="scrollToIndex">要滚动到的项目索引(从1开始)，0或负数表示不滚动</param>
        /// <param name="duration">滚动动画持续时间，0表示立即跳转</param>
        public virtual void ShowList(int itemCount, int scrollToIndex = 0, float duration = 0f)
        {
            try
            {
                if (!m_IsInitialized || m_ContentRectTransform == null)
                {
                    return;
                }
                
                // 如果项目数量为0，直接返回
                if (itemCount <= 0)
                {
                    // 清理已有数据
                    ClearVisibleCells();
                    m_TotalCount = 0;
                    
                    // 重置动画状态
                    m_AnimatedItems.Clear();
                    if (m_AnimationManager != null)
                    {
                        m_AnimationManager.ResetAnimationState();
                    }
                    
                    return;
                }
                
                // 检查Content是否激活，如果未激活则保存参数等待激活后处理
                if (m_Content == null || !m_Content.activeInHierarchy)
                {
                    // 保存显示参数
                    m_PendingShowList = new PendingShowListParams(itemCount, scrollToIndex, duration);
                    
                    // 如果Content存在但未激活，尝试激活它
                    if (m_Content != null && !m_Content.activeInHierarchy)
                    {
                        m_Content.SetActive(true);
                        
                        // 检查是否激活成功
                        if (m_Content.activeInHierarchy)
                        {
                            // 清空待显示参数，因为下面会继续处理
                            m_PendingShowList = null;
                        }
                        else
                        {
                            return; // 激活失败，返回等待Update中的监听处理
                        }
                    }
                    else
                    {
                        return; // Content为空或无法激活，返回等待Update中的监听处理
                    }
                }
                
                // 先停止所有正在进行的动画
                if (m_AnimationManager != null)
                {
                    m_AnimationManager.StopAllAnimations(true); // 变更为true，确保动画跳到结束状态
                }
                
                // 确保所有项目的透明度被还原，包括缓存区的项目
                if (m_Content != null)
                {
                    // 遍历Content下的所有子对象，确保透明度正确
                    for (int i = 0; i < m_Content.transform.childCount; i++)
                    {
                        GameObject cellObj = m_Content.transform.GetChild(i).gameObject;
                        if (cellObj != null && cellObj.activeInHierarchy)
                        {
                            CanvasGroup canvasGroup = cellObj.GetComponent<CanvasGroup>();
                            if (canvasGroup != null)
                            {
                                canvasGroup.alpha = 1.0f; // 强制设置透明度为1.0
                            }
                        }
                    }
                }

                // 无条件清除动画状态，确保每次调用ShowList时都会重新播放动画
                m_AnimatedItems.Clear();
                if (m_AnimationManager != null)
                {
                    m_AnimationManager.ResetAnimationState();
                }

                // 重置显示索引
                m_FirstVisibleIndex = -1;
                m_LastVisibleIndex = -1;
                
                // 检查Content和ContentRectTransform是否仍然有效
                if (m_Content == null || m_ContentRectTransform == null)
                {
                    return;
                }
                
                // 确保Content初始尺寸至少与视口相同
                Rect viewportRect = m_ViewportRectTransform.rect;
                m_ViewportWidth = viewportRect.width;
                m_ViewportHeight = viewportRect.height;
                
                // 计算行数
                int rowCount = Mathf.CeilToInt((float)itemCount / m_Row);
                
                // 计算所需Content尺寸（不计算缓冲区时）
                float requiredWidth = m_ViewportWidth;
                float requiredHeight = m_ViewportHeight;
                
                if (m_Direction == e_Direction.Vertical)
                {
                    // 计算实际所需高度
                    float contentHeight = (rowCount > 0 ? m_Spacing * (rowCount - 1) : 0) 
                                         + m_CellHeight * rowCount 
                                         + m_Padding.top + m_Padding.bottom;
                    
                    // 实际内容高度应该至少等于视口高度
                    requiredHeight = Mathf.Max(contentHeight, m_ViewportHeight);
                    
                    // 计算所需的宽度，直接基于项目数量和项目尺寸
                    float requiredContentWidth = 0;
                    if (m_Row > 1) {
                        // 多列情况：直接使用项目原始宽度
                        requiredContentWidth = m_CellWidth * m_Row + m_Spacing * (m_Row - 1) + m_Padding.left + m_Padding.right;
                    } else {
                        // 单列情况
                        requiredContentWidth = m_CellWidth + m_Padding.left + m_Padding.right;
                    }
                    
                    // 设置Content尺寸
                    m_ContentWidth = Mathf.Max(requiredContentWidth, m_ViewportWidth);
                    m_ContentHeight = requiredHeight;
                }
                else
                {
                    // 计算实际所需宽度
                    float contentWidth = (rowCount > 0 ? m_Spacing * (rowCount - 1) : 0) 
                                        + m_CellWidth * rowCount 
                                        + m_Padding.left + m_Padding.right;
                    
                    // 实际内容宽度应该至少等于视口宽度
                    requiredWidth = Mathf.Max(contentWidth, m_ViewportWidth);
                    
                    // 计算高度，直接基于项目数量和项目尺寸
                    float requiredContentHeight = 0;
                    if (m_Row > 1) {
                        // 多行情况：直接使用项目原始高度
                        requiredContentHeight = m_CellHeight * m_Row + m_Spacing * (m_Row - 1) + m_Padding.top + m_Padding.bottom;
                    } else {
                        // 单行情况
                        requiredContentHeight = m_CellHeight + m_Padding.top + m_Padding.bottom;
                    }
                    
                    // 设置Content尺寸
                    m_ContentWidth = requiredWidth;
                    m_ContentHeight = Mathf.Max(requiredContentHeight, m_ViewportHeight);
                }
                
                // 设置Content尺寸
                m_ContentRectTransform.sizeDelta = new Vector2(m_ContentWidth, m_ContentHeight);
                
                // 如果需要滚动到特定索引，先计算目标位置
                Vector2 targetScrollPosition = Vector2.zero;
                
                // 直接使用从1开始的索引
                bool needScrollToIndex = scrollToIndex > 0 && scrollToIndex <= itemCount;
                
                if (needScrollToIndex)
                {
                    // 获取当前项所在行
                    int internalScrollToIndex = scrollToIndex - 1; // 转为从0开始的索引
                    int indexRow = Mathf.FloorToInt(internalScrollToIndex / m_Row);
                    int lastRowIndex = Mathf.FloorToInt((itemCount - 1) / m_Row);
                    
                    // 计算可见行数
                    int visibleRows = 0;
                    if (m_Direction == e_Direction.Vertical)
                    {
                        // 修正：考虑内边距和每行间距的影响
                        visibleRows = Mathf.FloorToInt((m_ViewportHeight - m_Padding.top - m_Padding.bottom) / (m_CellHeight + m_Spacing));
                        // 确保至少是1
                        visibleRows = Mathf.Max(1, visibleRows);
                    }
                    else
                    {
                        // 修正：考虑内边距和每列间距的影响
                        visibleRows = Mathf.FloorToInt((m_ViewportWidth - m_Padding.left - m_Padding.right) / (m_CellWidth + m_Spacing));
                        // 确保至少是1
                        visibleRows = Mathf.Max(1, visibleRows);
                    }
                    
                    // 如果是最后几行，需要特殊处理确保内容不会出现大片空白
                    if (indexRow > lastRowIndex - visibleRows)
                    {
                        // 计算最合适的滚动位置：显示最后visibleRows行
                        // 对于最后几行的项目，始终滚动到一个固定位置（最后一屏的起始位置）
                        int lastScreenFirstRow = Mathf.Max(0, lastRowIndex - visibleRows + 1);
                        
                        // 使用这个固定位置的索引
                        internalScrollToIndex = lastScreenFirstRow * m_Row;
                    }
                    
                    // 预先计算目标滚动位置
                    targetScrollPosition = CalculateScrollPosition(internalScrollToIndex);
                }
                else
                {
                    // 设置Content初始位置
                    if (m_Direction == e_Direction.Vertical)
                    {
                        // 垂直滚动：设置Content初始位置使第一个项目位于顶部
                        targetScrollPosition = new Vector2(0, 0);
                    }
                    else 
                    {
                        // 水平滚动：设置Content初始位置使第一个项目位于左侧
                        targetScrollPosition = new Vector2(0, 0);
                    }
                }
                
                // 安全释放旧资源
                try
                {
                    // 确保在创建新列表前清除所有可见单元格
                    ClearVisibleCells();
                    
                    // 在数据数量变化时，完全清理旧数据
                    if (m_TotalCount != itemCount && m_CellInfos != null)
                    {
                        // 释放旧资源
                        for (int i = 0; i < m_CellInfos.Length; i++)
                        {
                            if (m_CellInfos[i].obj != null)
                            {
                                if (m_CellPool != null)
                                {
                                    m_CellPool.RecycleObject(m_CellInfos[i].obj);
                                }
                                m_CellInfos[i].obj = null;
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.LogError($"清理单元格时出错: {ex.Message}\n{ex.StackTrace}");
                }
                
                // 检查对象池状态
                if (m_CellPool == null && m_Content != null && m_CellGameObject != null)
                {
                    // 如果对象池为空但有必要组件，尝试重新创建
                    m_CellPool = new ObjectPool(m_CellGameObject, m_Content.transform, m_PoolPreloadCount, m_MaxPoolSize);
                }
                
                // 创建新的列表项信息数组
                m_CellInfos = new CellInfo[itemCount];
                
                // 计算所有Cell的位置
                for (int i = 0; i < itemCount; i++)
                {
                    CellInfo cellInfo = new CellInfo();
                    cellInfo.dataIndex = i;
                    cellInfo.isVisible = false;
                    
                    // 计算坐标
                    int rowIndex = Mathf.FloorToInt(i / m_Row);
                    int colIndex = i % m_Row;
                    
                    if (m_Direction == e_Direction.Vertical)
                    {
                        // 垂直布局：从顶部向下计算位置
                        
                        // 计算Y轴位置（从顶部向下）
                        float yPos = -m_Padding.top - rowIndex * (m_CellHeight + m_Spacing);
                        
                        // 计算X轴位置（考虑多列的情况）
                        float xPos = m_Padding.left;
                        if (m_Row > 1)
                        {
                            // 不再根据容器宽度计算项宽度，直接使用Cell的原始宽度
                            float itemWidth = m_CellWidth;
                            
                            // 计算项在X轴的位置，确保正确应用间距
                            xPos = m_Padding.left + colIndex * (itemWidth + m_Spacing);
                        }
                        
                        cellInfo.position = new Vector3(xPos, yPos, 0);
                    }
                    else
                    {
                        // 水平布局：从左向右计算位置
                        
                        // 计算X轴位置（从左向右）
                        float xPos = m_Padding.left + rowIndex * (m_CellWidth + m_Spacing);
                        
                        // 计算Y轴位置（考虑多行的情况）
                        float yPos = -m_Padding.top;
                        if (m_Row > 1)
                        {
                            // 不再根据容器高度计算项高度，直接使用Cell的原始高度
                            float itemHeight = m_CellHeight;
                            
                            // 计算项在Y轴的位置，确保正确应用间距
                            yPos = -m_Padding.top - colIndex * (itemHeight + m_Spacing);
                        }
                        
                        cellInfo.position = new Vector3(xPos, yPos, 0);
                    }
                    
                    cellInfo.obj = null;
                    
                    m_CellInfos[i] = cellInfo;
                }
                
                // 更新可见Cell
                m_TotalCount = itemCount;
                
                // 检查对象池是否初始化
                if (m_CellPool == null)
                {
                    Debug.LogError("无法显示列表: 对象池未初始化");
                    return;
                }
                
                // 检查基本组件是否仍然有效
                if (m_Content == null || !m_Content.activeInHierarchy || m_ContentRectTransform == null)
                {
                    Debug.LogError("无法更新可见单元格: Content为空或未激活");
                    return;
                }
                
                // 设置初始滚动位置
                if (duration <= 0 || !needScrollToIndex)
                {
                    // 无动画或不需要滚动时，直接设置位置
                    m_ContentRectTransform.anchoredPosition = targetScrollPosition;
                }
                
                // 立即更新可见项目，确保水平列表的第一列正确显示
                UpdateVisibleCells();
                
                // 为确保第一次加载时能正确显示第一列，延迟一帧再次更新
                StartCoroutine(DelayedInitialUpdate());
                
                // 更新箭头显示
                if (m_IsShowArrow && (m_PointingFirstArrow != null || m_PointingEndArrow != null))
                {
                    OnScrollArrowUpdate(Vector2.zero);
                }
                
                // 如果需要带动画滚动到指定索引
                if (needScrollToIndex && duration > 0)
                {
                    // 使用协程实现平滑滚动
                    StartCoroutine(SmoothScrollTo(targetScrollPosition, duration));
                }
            }
            catch (System.Exception ex)
            {
                Debug.LogError($"显示列表时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 更新布局和属性
        public void RefreshView(int newRowCount, int newItemCount)
        {
            if (!m_IsInitialized)
                return;
                
            // 保存当前位置状态以便还原
            Vector2 currentPos = m_ContentRectTransform != null ? 
                                 m_ContentRectTransform.anchoredPosition : Vector2.zero;
            
            // 彻底清理所有数据和对象
            ClearAll();
            
            // 更新行数
            m_Row = newRowCount > 0 ? newRowCount : 1;
            
            // 确保初始化已完成并对象池有效
            if (m_CellPool == null && m_CellGameObject != null && m_Content != null)
            {
                m_CellPool = new ObjectPool(m_CellGameObject, m_Content.transform, m_PoolPreloadCount, m_MaxPoolSize);
            }
            
            // 重新显示列表
            ShowList(newItemCount);
        }
        #endregion

        #region 可见性和对象池管理
        // 更新可见的Cell
        protected virtual void UpdateVisibleCells()
        {
            // 首先检查基本条件
            if (m_CellInfos == null || m_CellInfos.Length == 0 || m_Content == null 
                || m_ContentRectTransform == null || m_ViewportRectTransform == null || m_CellPool == null)
            {
                return; // 如果任何必要引用为空，直接返回避免崩溃
            }

            // 缓存常用变量，避免重复访问
            Vector2 contentPos = m_ContentRectTransform.anchoredPosition;
            bool isVertical = m_Direction == e_Direction.Vertical;
            Rect visibleRect;
            
            // 复用计算逻辑
            if (m_ExtremeCacheMode)
            {
                if (isVertical)
                {
                    float top = -contentPos.y;
                    visibleRect = new Rect(0, top - m_ViewportHeight, m_ViewportWidth, m_ViewportHeight);
                }
                else
                {
                    float left = -contentPos.x;
                    visibleRect = new Rect(left, 0, m_ViewportWidth, m_ViewportHeight);
                }
            }
            else if (m_UseCacheCountMode)
            {
                // 与极致模式相同的计算方式，区别在IsPositionVisible的计算中
                if (isVertical)
                {
                    float top = -contentPos.y;
                    visibleRect = new Rect(0, top - m_ViewportHeight, m_ViewportWidth, m_ViewportHeight);
                }
                else
                {
                    float left = -contentPos.x;
                    visibleRect = new Rect(left, 0, m_ViewportWidth, m_ViewportHeight);
                }
            }
            else
            {
                // 原始的基于距离的缓存策略
                // 计算考虑间距的预加载缓冲区大小
                float actualBufferZone = isVertical ? 
                                        Mathf.Max(m_CellHeight + m_Spacing, m_PreloadBufferZone) :
                                        Mathf.Max(m_CellWidth + m_Spacing, m_PreloadBufferZone);
                
                if (isVertical)
                {
                    // 垂直滚动时的可见区域
                    float top = -contentPos.y;
                    float bottom = top - m_ViewportHeight;
                    
                    // 设置预加载边距
                    float topMargin = m_Spacing + m_CellHeight * 0.2f;
                    float bottomMargin = m_CellHeight * 1.5f;
                    
                    // 基本可见区域
                    top += topMargin;
                    bottom -= bottomMargin;
                    
                    // 根据滚动方向动态调整缓冲区
                    if (contentPos.y > 0) // 向上滚动
                    {
                        float scrolledDistance = Mathf.Abs(contentPos.y);
                        float additionalBuffer = Mathf.Max(m_CellHeight * 2.0f, scrolledDistance * 0.8f);
                        bottom -= additionalBuffer;
                    }
                    else if (contentPos.y < 0) // 向下滚动
                    {
                        float scrolledDistance = Mathf.Abs(contentPos.y);
                        float additionalBuffer = Mathf.Max(m_CellHeight * 2.0f, scrolledDistance * 0.8f);
                        top += additionalBuffer;
                    }
                    else // 初始位置
                    {
                        top += m_CellHeight * (m_Row * 2);
                        bottom -= m_CellHeight * 10;
                    }
                    
                    visibleRect = new Rect(0, bottom, m_ViewportWidth, top - bottom);
                }
                else
                {
                    // 水平滚动的计算逻辑 (与垂直类似但方向不同)
                    float left = -contentPos.x;
                    float right = left + m_ViewportWidth;
                    
                    float leftMargin = m_Spacing + m_CellWidth * 0.2f;
                    float rightMargin = m_CellWidth * 1.5f;
                    
                    left -= leftMargin;
                    right += rightMargin;
                    
                    // 根据滚动方向动态调整
                    if (contentPos.x > 0) // 向左滚动
                    {
                        float scrolledDistance = Mathf.Abs(contentPos.x);
                        float additionalBuffer = Mathf.Max(m_CellWidth * 1.5f, scrolledDistance * 0.8f);
                        right += additionalBuffer;
                    }
                    else if (contentPos.x < 0) // 向右滚动
                    {
                        float scrolledDistance = Mathf.Abs(contentPos.x);
                        float additionalBuffer = Mathf.Max(m_CellWidth * 1.5f, scrolledDistance * 0.8f);
                        left -= additionalBuffer;
                    }
                    else // 初始位置
                    {
                        left -= m_CellWidth * (m_Row * 2);
                        right += m_CellWidth * 10;
                    }
                    
                    visibleRect = new Rect(left, 0, right - left, m_ViewportHeight);
                }
            }

            // 获取真实可见区域（不含缓冲区）
            Rect realVisibleRect = GetRealVisibleRect();
            
            // 记录新的可见索引
            int newFirstVisible = -1;
            int newLastVisible = -1;
            
            // 使用对象池模式的列表，避免每次创建新列表
            List<KeyValuePair<GameObject, int>> cellsToAnimate = new List<KeyValuePair<GameObject, int>>(m_CellInfos.Length);
            
            // 临时存储此次更新中的真实可见项目 - 使用值类型提高性能
            HashSet<int> currentRealVisibleItems = new HashSet<int>();
            HashSet<int> itemsAddedToAnimateList = new HashSet<int>();
            
            if (m_Content == null || !m_Content.activeInHierarchy)
                return;

            // 循环优化：缓存长度，减少数组边界检查
            int cellCount = m_CellInfos.Length;
            for (int i = 0; i < cellCount; i++)
            {
                CellInfo cellInfo = m_CellInfos[i];
                bool wasVisible = cellInfo.isVisible;
                
                // 使用预先缓存的变量减少参数传递开销
                bool isItemVisible;
                try { isItemVisible = IsPositionVisible(cellInfo.position, visibleRect); }
                catch (System.Exception ex) { 
                    Debug.LogError($"检查项目可见性时出错，项目索引: {i}, 位置: {cellInfo.position}, 错误: {ex.Message}\n{ex.StackTrace}");
                    continue; 
                }
                
                if (isItemVisible)
                {
                    // 记录可见范围 - 使用直接赋值减少条件判断
                    if (newFirstVisible == -1) newFirstVisible = i;
                    newLastVisible = i;
                    
                    // 检查是否在真实可见区域内
                    bool isInRealVisibleArea = IsPositionInRealVisibleArea(cellInfo.position, realVisibleRect);
                    if (isInRealVisibleArea)
                    {
                        currentRealVisibleItems.Add(i);
                    }
                    
                    // 不可见变为可见：创建Cell
                    if (!wasVisible)
                    {
                        // 避免重复检查
                        if (m_CellPool == null || m_Content == null || !m_Content.activeInHierarchy)
                            continue;
                        
                        try
                        {
                            // 判断是否需要动画 - 使用逻辑短路减少计算
                            bool needAnimation = false;
                            
                            if (m_EnableItemAnimation && isInRealVisibleArea && 
                                (!m_OnlyAnimateFirstTime || !m_AnimatedItems.Contains(i)))
                            {
                                needAnimation = true;
                            }

                            // 从对象池获取或创建新对象
                            GameObject cell = m_CellPool.GetObject();
                            if (cell != null)
                            {
                                // 设置Cell属性
                                Transform cellTransform = cell.transform;
                                cellTransform.SetParent(m_Content.transform, false);
                                cellTransform.localScale = Vector3.one;
                                
                                RectTransform rectTrans = cell.GetComponent<RectTransform>();
                                
                                // 设置位置 - 直接设置，让动画管理器控制动画效果
                                if (rectTrans != null)
                                {
                                    // 直接设置基础位置，动画位置由动画管理器控制
                                    rectTrans.anchoredPosition = cellInfo.position;
                                }
                                
                                cell.name = i.ToString();
                                
                                // 更新引用和状态
                                cellInfo.obj = cell;
                                cellInfo.isVisible = true;
                                m_CellInfos[i] = cellInfo;
                                
                                // 更新Cell内容
                                UpdateCellContent(cell, i);
                                
                                // 处理动画
                                if (needAnimation)
                                {
                                    // 如果使用动画管理器，先准备动画状态
                                    if (m_AnimationManager != null)
                                    {
                                        m_AnimationManager.PrepareItemForAnimation(cell, i, cellInfo.position);
                                    }
                                    
                                    cellsToAnimate.Add(new KeyValuePair<GameObject, int>(cell, i));
                                    itemsAddedToAnimateList.Add(i);
                                    if (m_OnlyAnimateFirstTime)
                                    {
                                        m_AnimatedItems.Add(i);
                                    }
                                }
                            }
                        }
                        catch (System.Exception ex)
                        {
                            Debug.LogError($"创建可见项目时出错，项目索引: {i}, 错误: {ex.Message}\n{ex.StackTrace}");
                            continue;
                        }
                    }
                }
                else if (wasVisible)
                {
                    // 可见变为不可见：回收Cell
                    GameObject cellObj = cellInfo.obj;
                    if (cellObj != null)
                    {
                        // 确保对象池存在
                        if (m_CellPool != null)
                        {
                            try { m_CellPool.RecycleObject(cellObj); }
                            catch (System.Exception ex) {
                                Debug.LogError($"回收单元格对象时出错 {i}: {ex.Message}\n{ex.StackTrace}");
                            }
                        }
                        
                        cellInfo.obj = null;
                        cellInfo.isVisible = false;
                        m_CellInfos[i] = cellInfo;
                    }
                }
            }
            
            // 更新可见索引范围
            m_FirstVisibleIndex = newFirstVisible;
            m_LastVisibleIndex = newLastVisible;
            
            // 检查原先不在真实可见区域但现在进入的项目
            if (m_EnableItemAnimation)
            {
                foreach (int index in currentRealVisibleItems)
                {
                    // 优化条件判断，减少重复操作
                    if (!m_RealVisibleItems.Contains(index) && 
                        (!m_OnlyAnimateFirstTime || !m_AnimatedItems.Contains(index)) && 
                        !itemsAddedToAnimateList.Contains(index))
                    {
                        CellInfo cellInfo = m_CellInfos[index];
                        GameObject cellObj = cellInfo.obj;
                        
                        if (cellObj != null && cellInfo.isVisible)
                        {
                            // 使用动画管理器准备动画
                            if (m_AnimationManager != null)
                            {
                                m_AnimationManager.PrepareItemForAnimation(cellObj, index, cellInfo.position);
                            }
                            
                            // 添加到待播放动画列表
                            cellsToAnimate.Add(new KeyValuePair<GameObject, int>(cellObj, index));
                            
                            if (m_OnlyAnimateFirstTime)
                            {
                                m_AnimatedItems.Add(index);
                            }
                        }
                    }
                }
            }
            
            // 更新真实可见项目记录
            m_RealVisibleItems = currentRealVisibleItems;
            
            // 播放动画
            if (cellsToAnimate.Count > 0)
            {
                try { PlayItemsAnimation(cellsToAnimate); }
                catch (System.Exception ex) {
                    Debug.LogError($"播放项目动画时出错: {ex.Message}\n{ex.StackTrace}");
                }
            }
        }

        // 为动画准备项目的初始状态 - 使用动画管理器
        protected virtual void PrepareItemForAnimation(GameObject cell)
        {
            if (cell == null || !cell.activeInHierarchy || !m_EnableItemAnimation) return;
            
            try
            {
                // 获取数据索引
                int cellIndex;
                if (!int.TryParse(cell.name, out cellIndex) || cellIndex < 0 || cellIndex >= m_CellInfos.Length)
                    return;
                
                // 获取基础位置
                Vector2 basePosition = m_CellInfos[cellIndex].position;
                
                // 使用动画管理器准备动画
                m_AnimationManager.PrepareItemForAnimation(cell, cellIndex, basePosition);
            }
            catch (Exception ex)
            {
                Debug.LogError($"准备动画时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 播放一组Cell项目的动画 - 使用动画管理器
        protected virtual void PlayItemsAnimation(List<KeyValuePair<GameObject, int>> cellsToAnimate)
        {
            if (cellsToAnimate == null || cellsToAnimate.Count == 0 || !m_EnableItemAnimation)
                return;
            
            try
            {
                // 收集基础位置
                List<Vector2> basePositions = new List<Vector2>(cellsToAnimate.Count);
                foreach (var pair in cellsToAnimate)
                {
                    int index = pair.Value;
                    if (index >= 0 && index < m_CellInfos.Length)
                    {
                        basePositions.Add(m_CellInfos[index].position);
                    }
                    else
                    {
                        basePositions.Add(Vector2.zero);
                    }
                }
                
                // 使用动画管理器播放动画
                m_AnimationManager.PlayItemsAnimation(cellsToAnimate, basePositions);
            }
            catch (System.Exception ex)
            {
                Debug.LogError($"启动动画协程时出错: {ex.Message}\n{ex.StackTrace}");
            }
        }

        // 设置是否启用项目动画
        public void SetEnableItemAnimation(bool enable)
        {
            m_EnableItemAnimation = enable;
        }
        
        // 设置是否只在首次填充时执行动画
        public void SetOnlyAnimateFirstTime(bool onlyFirstTime)
        {
            m_OnlyAnimateFirstTime = onlyFirstTime;
            if (m_AnimationManager != null)
            {
                AnimationManager.AnimationParams parameters = new AnimationManager.AnimationParams();
                parameters.onlyFirstTime = onlyFirstTime;
                parameters.duration = m_AnimationDuration;
                parameters.delay = m_AnimationOffset;
                m_AnimationManager.SetDefaultParams(parameters);
            }
        }
        
        // 设置动画持续时间
        public void SetAnimationDuration(float duration)
        {
            m_AnimationDuration = Mathf.Max(0.1f, duration);
            if (m_AnimationManager != null)
            {
                AnimationManager.AnimationParams parameters = new AnimationManager.AnimationParams();
                parameters.duration = m_AnimationDuration;
                parameters.delay = m_AnimationOffset;
                parameters.onlyFirstTime = m_OnlyAnimateFirstTime;
                m_AnimationManager.SetDefaultParams(parameters);
            }
        }
        
        // 设置动画延迟
        public void SetAnimationOffset(float offset)
        {
            m_AnimationOffset = Mathf.Max(0f, offset);
            if (m_AnimationManager != null)
            {
                AnimationManager.AnimationParams parameters = new AnimationManager.AnimationParams();
                parameters.delay = m_AnimationOffset;
                parameters.duration = m_AnimationDuration;
                parameters.onlyFirstTime = m_OnlyAnimateFirstTime;
                m_AnimationManager.SetDefaultParams(parameters);
            }
        }
        
        // 重置动画状态
        public void ResetAnimationState()
        {
            m_AnimatedItems.Clear();
            if (m_AnimationManager != null)
            {
                m_AnimationManager.ResetAnimationState();
            }
        }
        #endregion

        #region 事件处理
        // 滚动事件监听
        protected virtual void ScrollRectListener(Vector2 value)
        {
            // 添加安全检查，确保组件已完全初始化
            if (!m_IsInitialized || m_CellInfos == null || m_CellPool == null)
            {
                return;
            }
            
            // 记录旧位置，用于判断滚动方向
            Vector2 oldPosition = m_ContentRectTransform.anchoredPosition;
            
            // 等待一帧执行更新，确保位置已更新
            StartCoroutine(DelayedScrollUpdate(oldPosition));
        }
        
        // 延迟更新滚动，用于正确判断滚动方向
        private System.Collections.IEnumerator DelayedScrollUpdate(Vector2 oldPosition)
        {
            // 等待一帧
            yield return null;
            
            // 获取当前位置
            Vector2 currentPosition = m_ContentRectTransform.anchoredPosition;
            
            // 判断是否有足够的滚动距离来触发动画重置
            // 避免微小滚动导致不必要的动画重置
            bool significantScroll = false;
            float scrollThreshold = (m_Direction == e_Direction.Vertical) ? (m_CellHeight * 0.2f) : (m_CellWidth * 0.2f);
            
            if (m_Direction == e_Direction.Vertical)
            {
                significantScroll = Mathf.Abs(currentPosition.y - oldPosition.y) > scrollThreshold;
            }
            else
            {
                significantScroll = Mathf.Abs(currentPosition.x - oldPosition.x) > scrollThreshold;
            }
            
            // 重置动画状态，确保滚动时新出现的项目也有动画效果
            // 仅在有足够滚动距离且需要动画时才重置
            if (significantScroll && m_EnableItemAnimation && !m_OnlyAnimateFirstTime)
            {
                m_AnimatedItems.Clear();
                if (m_AnimationManager != null)
                {
                    m_AnimationManager.ResetAnimationState();
                }
            }
            
            UpdateVisibleCells();
            
            // 更新所有活动项的基础位置（用于坐标叠加算法）
            if (m_AnimationManager != null && m_CellInfos != null)
            {
                for (int i = 0; i < m_CellInfos.Length; i++)
                {
                    if (m_CellInfos[i].isVisible && m_CellInfos[i].obj != null)
                    {
                        m_AnimationManager.UpdateItemBasePosition(i, m_CellInfos[i].position);
                    }
                }
            }
        }

        // 更新箭头显示
        protected void OnScrollArrowUpdate(Vector2 value)
        {
            if (!m_IsInitialized || !m_IsShowArrow || (m_PointingFirstArrow == null && m_PointingEndArrow == null) 
                || m_ScrollRect == null)
            {
                return;
            }

            float normalizedPos = m_Direction == e_Direction.Vertical ? 
                                 m_ScrollRect.verticalNormalizedPosition : 
                                 m_ScrollRect.horizontalNormalizedPosition;
                                 
            // 检查内容是否足够大，需要滚动
            bool contentLargerThanViewport = false;
            
            if (m_Direction == e_Direction.Vertical)
            {
                contentLargerThanViewport = m_ContentHeight > m_ViewportHeight + 10f;
            }
            else
            {
                contentLargerThanViewport = m_ContentWidth > m_ViewportWidth + 10f;
            }
            
            // 如果内容不需要滚动，隐藏箭头
            if (!contentLargerThanViewport)
            {
                if (m_PointingFirstArrow != null) m_PointingFirstArrow.SetActive(false);
                if (m_PointingEndArrow != null) m_PointingEndArrow.SetActive(false);
                return;
            }
            
            // 根据滚动位置显示/隐藏箭头
            // 注意：normalizedPos为1表示顶部/左侧，为0表示底部/右侧
            if (normalizedPos >= 0.98f)
            {
                // 已滚动到起始位置
                if (m_PointingFirstArrow != null) m_PointingFirstArrow.SetActive(false);
                if (m_PointingEndArrow != null) m_PointingEndArrow.SetActive(true);
            }
            else if (normalizedPos <= 0.02f)
            {
                // 已滚动到末尾位置
                if (m_PointingFirstArrow != null) m_PointingFirstArrow.SetActive(true);
                if (m_PointingEndArrow != null) m_PointingEndArrow.SetActive(false);
            }
            else
            {
                // 中间位置，两个箭头都显示
                if (m_PointingFirstArrow != null) m_PointingFirstArrow.SetActive(true);
                if (m_PointingEndArrow != null) m_PointingEndArrow.SetActive(true);
            }
        }

        // 拖拽事件处理
        public virtual void OnBeginDrag(PointerEventData eventData) { }

        public virtual void OnDrag(PointerEventData eventData) { }

        public virtual void OnEndDrag(PointerEventData eventData) { }
        #endregion

        #region 清理与销毁
        // 清除可见Cell但保留列表结构
        protected void ClearVisibleCells()
        {
            if (m_CellInfos != null)
            {
                for (int i = 0; i < m_CellInfos.Length; i++)
                {
                    if (m_CellInfos[i].obj != null)
                    {
                        if (m_CellPool != null)
                        {
                            try
                            {
                                m_CellPool.RecycleObject(m_CellInfos[i].obj);
                            }
                            catch (System.Exception ex)
                            {
                                Debug.LogError($"回收单元格对象时出错 {i}: {ex.Message}\n{ex.StackTrace}");
                            }
                        }
                        m_CellInfos[i].obj = null;
                        m_CellInfos[i].isVisible = false;
                    }
                }
            }
        }

        // 清除所有Cell
        public void ClearAll()
        {
            // 首先安全清除所有可见单元格
            ClearVisibleCells();
            
            // 确保所有单元格对象都被回收到对象池
            if (m_CellInfos != null)
            {
                for (int i = 0; i < m_CellInfos.Length; i++)
                {
                    if (m_CellInfos[i].obj != null)
                    {
                        if (m_CellPool != null)
                        {
                            m_CellPool.RecycleObject(m_CellInfos[i].obj);
                        }
                        m_CellInfos[i].obj = null;
                        m_CellInfos[i].isVisible = false;
                    }
                }
            }
            
            // 清空数据引用
            m_CellInfos = null;
            m_FirstVisibleIndex = -1;
            m_LastVisibleIndex = -1;
            m_TotalCount = 0;
            m_AnimatedItems.Clear();  // 清除动画记录
        }

        // 释放所有资源，包括池中对象
        public void DisposeAll()
        {
            if (m_FuncCallBackFunc != null) m_FuncCallBackFunc = null;
            
            ClearVisibleCells();
            
            if (m_CellPool != null)
            {
                m_CellPool.Clear();
                m_CellPool = null;
            }
            
            // 释放动画管理器
            if (m_AnimationManager != null)
            {
                m_AnimationManager.Dispose();
                m_AnimationManager = null;
            }
            
            m_CellInfos = null;
        }

        // Unity销毁回调
        protected void OnDestroy()
        {
            DisposeAll();
        }
        #endregion

        #region 公共工具方法
        // 更新视口大小（例如屏幕旋转后）
        public void UpdateViewportSize()
        {
            if (!m_IsInitialized) return;
            
            // 记录当前第一个可见项的索引，用于保持滚动位置
            int currentVisibleIndex = m_FirstVisibleIndex;
            
            Rect viewportRect = m_ViewportRectTransform.rect;
            m_ViewportWidth = viewportRect.width;
            m_ViewportHeight = viewportRect.height;
            
            // 如果列表已显示，需要更新Content尺寸
            if (m_TotalCount > 0)
            {
                // 如果有可见项，则滚动到当前位置；否则只刷新布局
                if (currentVisibleIndex >= 0 && currentVisibleIndex < m_TotalCount)
                {
                    ShowList(m_TotalCount, currentVisibleIndex, 0f); // 立即滚动，无动画
                }
                else
                {
                    ShowList(m_TotalCount);
                }
            }
        }
        
        // 获取当前可见项的数量
        public int GetVisibleItemCount()
        {
            if (m_FirstVisibleIndex < 0 || m_LastVisibleIndex < 0)
                return 0;
                
            return m_LastVisibleIndex - m_FirstVisibleIndex + 1;
        }
        
        // 滚动到指定索引项
        public void ScrollToIndex(int index, float duration = 0.3f)
        {
            // 直接使用从1开始的索引
            if (!m_IsInitialized || m_CellInfos == null || index <= 0 || index > m_CellInfos.Length)
                return;
                
            // 获取当前项所在行
            int internalIndex = index - 1; // 转为从0开始的索引
            int indexRow = Mathf.FloorToInt(internalIndex / m_Row);
            int lastRowIndex = Mathf.FloorToInt((m_TotalCount - 1) / m_Row);
            
            // 计算可见行数
            int visibleRows = 0;
            if (m_Direction == e_Direction.Vertical)
            {
                // 修正：考虑内边距和每行间距的影响
                visibleRows = Mathf.FloorToInt((m_ViewportHeight - m_Padding.top - m_Padding.bottom) / (m_CellHeight + m_Spacing));
                // 确保至少是1
                visibleRows = Mathf.Max(1, visibleRows);
            }
            else
            {
                // 修正：考虑内边距和每列间距的影响
                visibleRows = Mathf.FloorToInt((m_ViewportWidth - m_Padding.left - m_Padding.right) / (m_CellWidth + m_Spacing));
                // 确保至少是1
                visibleRows = Mathf.Max(1, visibleRows);
            }
            
            // 计算合适的目标位置，确保被点击的项完全可见
            Vector2 targetPosition;
            
            // 如果是最后几行，需要特殊处理确保内容不会出现大片空白
            if (indexRow > lastRowIndex - visibleRows)
            {
                // 计算最合适的滚动位置：显示最后visibleRows行
                // 对于最后几行的项目，始终滚动到一个固定位置（最后一屏的起始位置）
                int lastScreenFirstRow = Mathf.Max(0, lastRowIndex - visibleRows + 1);
                
                // 计算这个固定位置
                targetPosition = CalculateScrollPosition(lastScreenFirstRow * m_Row);
            }
            else
            {
                // 正常情况：直接滚动到目标位置
                targetPosition = CalculateScrollPosition(internalIndex);
            }
            
            // 使用动画滚动到目标位置
            if (duration > 0)
            {
                StartCoroutine(SmoothScrollTo(targetPosition, duration));
            }
            else
            {
                // 直接设置位置
                m_ContentRectTransform.anchoredPosition = targetPosition;
                UpdateVisibleCells();
            }
        }
        
        // 计算滚动位置
        private Vector2 CalculateScrollPosition(int index)
        {
            int rowIndex = Mathf.FloorToInt(index / m_Row);
            Vector2 currentPos = m_ContentRectTransform.anchoredPosition;
            
            if (m_Direction == e_Direction.Vertical)
            {
                // 垂直滚动：使用顶部锚点
                // 计算要显示的项目的顶部位置，确保应用间距
                float yPos = m_Padding.top;
                // 添加之前所有行的高度和间距
                if (rowIndex > 0) {
                    yPos += rowIndex * m_CellHeight + (rowIndex - 1) * m_Spacing;
                }
                
                // 返回需要设置的Content位置：向上滚动时为负值
                return new Vector2(currentPos.x, yPos);
            }
            else
            {
                // 水平滚动：使用左侧锚点
                // 计算要显示的项目的左侧位置，确保应用间距
                float xPos = m_Padding.left;
                // 添加之前所有列的宽度和间距
                if (rowIndex > 0) {
                    xPos += rowIndex * m_CellWidth + (rowIndex - 1) * m_Spacing;
                }
                
                // 返回需要设置的Content位置：向左滚动时为负值
                return new Vector2(xPos, currentPos.y);
            }
        }
        
        // 平滑滚动协程
        private System.Collections.IEnumerator SmoothScrollTo(Vector2 targetPos, float duration)
        {
            Vector2 startPos = m_ContentRectTransform.anchoredPosition;
            float elapsed = 0;
            
            while (elapsed < duration)
            {
                elapsed += Time.deltaTime;
                float t = Mathf.Clamp01(elapsed / duration);
                // 使用缓动函数使动画更平滑
                t = Mathf.SmoothStep(0, 1, t);
                
                m_ContentRectTransform.anchoredPosition = Vector2.Lerp(startPos, targetPos, t);
                UpdateVisibleCells();
                
                yield return null;
            }
            
            // 确保最终位置准确
            m_ContentRectTransform.anchoredPosition = targetPos;
            UpdateVisibleCells();
        }

        // 设置对象池最大大小
        public void SetMaxPoolSize(int maxSize)
        {
            m_MaxPoolSize = maxSize;
            if (m_CellPool != null)
            {
                m_CellPool.SetMaxSize(maxSize);
            }
        }
        
        // 获取当前对象池中的对象数量
        public int GetPooledObjectCount()
        {
            if (m_CellPool != null)
            {
                return m_CellPool.PooledCount;
            }
            return 0;
        }
        #endregion

        #region 延迟初始化更新
        // 延迟初始化更新协程，确保水平列表首次加载时第一列能正确显示
        private System.Collections.IEnumerator DelayedInitialUpdate()
        {
            // 等待一帧
            yield return null;
            // 再次更新可见项目
            UpdateVisibleCells();
            // 确保边界判断正确
            yield return null;
            UpdateVisibleCells();
        }
        #endregion

        #region 缓存区控制
        // 设置极致缓存模式
        public void SetExtremeCacheMode(bool enabled)
        {
            if (m_ExtremeCacheMode != enabled)
            {
                m_ExtremeCacheMode = enabled;
                // 启用极致缓存模式时，禁用数量模式
                if (enabled)
                {
                    m_UseCacheCountMode = false;
                }
                // 刷新所有可见项
                if (m_IsInitialized && m_CellInfos != null)
                {
                    UpdateVisibleCells();
                }
            }
        }

        // 设置数量模式缓存
        public void SetCacheCountMode(bool enabled, int beforeCount = 0, int afterCount = 0)
        {
            if (m_UseCacheCountMode != enabled || m_BeforeCacheCount != beforeCount || m_AfterCacheCount != afterCount)
            {
                m_UseCacheCountMode = enabled;
                m_BeforeCacheCount = Mathf.Max(0, beforeCount);
                m_AfterCacheCount = Mathf.Max(0, afterCount);
                
                // 启用数量模式时，禁用极致缓存模式
                if (enabled)
                {
                    m_ExtremeCacheMode = false;
                }
                
                // 刷新所有可见项
                if (m_IsInitialized && m_CellInfos != null)
                {
                    UpdateVisibleCells();
                }
            }
        }

        // 设置距离模式缓存
        public void SetDistanceCacheMode(float preloadBufferZone)
        {
            if (m_UseCacheCountMode || m_ExtremeCacheMode || m_PreloadBufferZone != preloadBufferZone)
            {
                m_UseCacheCountMode = false;
                m_ExtremeCacheMode = false;
                m_PreloadBufferZone = Mathf.Max(0, preloadBufferZone);
                
                // 刷新所有可见项
                if (m_IsInitialized && m_CellInfos != null)
                {
                    UpdateVisibleCells();
                }
            }
        }
        #endregion

        // 获取真实可见区域（不含缓冲区）
        protected Rect GetRealVisibleRect()
        {
            if (m_ContentRectTransform == null || m_ViewportRectTransform == null)
                return new Rect(0, 0, 0, 0);
                
            Vector2 contentPos = m_ContentRectTransform.anchoredPosition;
            
            // 计算真实可见区域，不包含任何缓冲区
            if (m_Direction == e_Direction.Vertical)
            {
                float top = -contentPos.y;
                float bottom = top - m_ViewportHeight;
                return new Rect(0, bottom, m_ViewportWidth, top - bottom);
            }
            else // 水平方向
            {
                float left = -contentPos.x;
                float right = left + m_ViewportWidth;
                return new Rect(left, 0, right - left, m_ViewportHeight);
            }
        }
        
        // 判断位置是否在真实可见区域内（不含缓冲区）
        protected bool IsPositionInRealVisibleArea(Vector3 position, Rect realVisibleRect)
        {
            if (m_Direction == e_Direction.Vertical)
            {
                // 垂直方向的判断
                float itemTop = position.y;
                float itemBottom = position.y - m_CellHeight;
                
                // 修改判断逻辑：只要项目有一部分在可视区域内即可
                // 项目底部在可视区域顶部以下，且项目顶部在可视区域底部以上
                bool bottomBelowViewportTop = itemBottom < realVisibleRect.yMax;
                bool topAboveViewportBottom = itemTop > realVisibleRect.yMin;
                
                return bottomBelowViewportTop && topAboveViewportBottom;
            }
            else
            {
                // 水平方向的判断
                float itemLeft = position.x;
                float itemRight = position.x + m_CellWidth;
                
                // 修改判断逻辑：只要项目有一部分在可视区域内即可
                // 项目右边在可视区域左边以右，且项目左边在可视区域右边以左
                bool rightRightOfViewportLeft = itemRight > realVisibleRect.xMin;
                bool leftLeftOfViewportRight = itemLeft < realVisibleRect.xMax;
                
                return rightRightOfViewportLeft && leftLeftOfViewportRight;
            }
        }

        // 上次记录的Content激活状态
        private bool m_LastContentActiveState = false;
        
        // 待处理的ShowList参数
        private class PendingShowListParams
        {
            public int itemCount;
            public int scrollToIndex;
            public float duration;
            
            public PendingShowListParams(int count, int index, float time)
            {
                itemCount = count;
                scrollToIndex = index;
                duration = time;
            }
        }
        
        // 待显示的列表参数
        private PendingShowListParams m_PendingShowList = null;
        
        // 在Update中监听Content激活状态
        private void Update()
        {
            // 仅在必要时进行Content激活状态检查
            if (m_Content == null || !m_IsInitialized) return;
            
            bool currentActiveState = m_Content.activeInHierarchy;
            
            // 仅在状态改变时处理，减少每帧的条件判断
            if (currentActiveState != m_LastContentActiveState)
            {
                // 仅处理从非活跃到活跃的转换
                if (currentActiveState)
                {
                    // 按需创建对象池
                    if (m_CellPool == null && m_CellGameObject != null)
                    {
                        m_CellPool = new ObjectPool(m_CellGameObject, m_Content.transform, 
                                                    m_PoolPreloadCount, m_MaxPoolSize);
                    }
                    
                    // 优先处理待显示的列表
                    if (m_PendingShowList != null)
                    {
                        var pendingParams = m_PendingShowList;
                        m_PendingShowList = null; // 立即清空，避免重复处理
                        
                        StartCoroutine(DelayedShowList(pendingParams.itemCount, 
                                                     pendingParams.scrollToIndex, 
                                                     pendingParams.duration));
                    }
                    // 否则仅刷新当前列表
                    else if (m_TotalCount > 0 && m_CellInfos != null && m_CellInfos.Length > 0)
                    {
                        StartCoroutine(DelayedRefresh());
                    }
                }
                
                m_LastContentActiveState = currentActiveState;
            }
        }
        
        // 延迟显示列表
        private System.Collections.IEnumerator DelayedShowList(int itemCount, int scrollToIndex, float duration)
        {
            yield return null; // 等待一帧
            
            // 简化条件判断
            if (m_Content != null && m_Content.activeInHierarchy)
            {
                ShowList(itemCount, scrollToIndex, duration);
            }
            else if (m_Content != null) // Content存在但未激活
            {
                // 保存参数待下次激活
                m_PendingShowList = new PendingShowListParams(itemCount, scrollToIndex, duration);
            }
        }
        
        // 延迟刷新协程
        private System.Collections.IEnumerator DelayedRefresh()
        {
            // 等待一帧，确保UI已经更新
            yield return null;
            
            // 先更新视口尺寸
            UpdateViewportSize();
            
            // 检查所有必要条件
            if (m_Content != null && m_Content.activeInHierarchy && m_CellPool != null)
            {
                UpdateVisibleCells();
            }
        }
        
        // 手动刷新方法，可以在外部调用
        public void RefreshList()
        {
            if (!m_IsInitialized || m_TotalCount <= 0)
                return;
                
            if (m_Content != null && m_Content.activeInHierarchy)
            {
                StartCoroutine(DelayedRefresh());
            }
        }

        // 获取动画管理器 - 公共接口，允许外部直接访问动画管理器进行高级自定义
        public AnimationManager GetAnimationManager()
        {
            return m_AnimationManager;
        }
        
        // 设置自定义动画参数
        public void SetCustomAnimationParams(AnimationManager.AnimationParams parameters)
        {
            if (m_AnimationManager != null && parameters != null)
            {
                m_AnimationManager.SetDefaultParams(parameters);
            }
        }

        // 停止所有当前正在播放的动画
        public void StopAllItemAnimations(bool jumpToEnd = true)
        {
            if (m_AnimationManager != null)
            {
                m_AnimationManager.StopAllAnimations(jumpToEnd);
            }
        }

        // 更新Cell内容
        protected void UpdateCellContent(GameObject cell, int index)
        {
            if (m_FuncCallBackFunc != null)
            {
                m_FuncCallBackFunc(cell, index + 1);
            }
        }

        // 判断位置是否在可见区域内
        protected bool IsPositionVisible(Vector3 position, Rect visibleRect)
        {
            // 判断是否使用极致缓存区模式
            if (m_ExtremeCacheMode)
            {
                // 极致模式下的判断逻辑
                if (m_Direction == e_Direction.Vertical)
                {
                    // 垂直方向判断 - 使用直接比较避免临时变量
                    return position.y - m_CellHeight < visibleRect.yMax && position.y > visibleRect.yMin;
                }
                else
                {
                    // 水平方向判断 - 使用直接比较避免临时变量
                    return position.x + m_CellWidth > visibleRect.xMin && position.x < visibleRect.xMax;
                }
            }
            else if (m_UseCacheCountMode)
            {
                // 在数量模式下，基于索引而非位置判断可见性
                if (m_Direction == e_Direction.Vertical)
                {
                    // 计算当前Item在第几行
                    int itemRowIndex = Mathf.FloorToInt((-position.y - m_Padding.top) / (m_CellHeight + m_Spacing));
                    if (itemRowIndex < 0) itemRowIndex = 0;
                    
                    // 计算可见区域的第一行和最后一行
                    float visibleTopPos = visibleRect.yMax;
                    float visibleBottomPos = visibleRect.yMin;
                    
                    int firstVisibleRow = Mathf.FloorToInt((-visibleTopPos - m_Padding.top) / (m_CellHeight + m_Spacing));
                    if (firstVisibleRow < 0) firstVisibleRow = 0;
                    
                    int lastVisibleRow = Mathf.FloorToInt((-visibleBottomPos - m_Padding.top) / (m_CellHeight + m_Spacing));
                    
                    // 基于缓存数量的可见性判断
                    return (itemRowIndex >= firstVisibleRow - m_BeforeCacheCount) && 
                           (itemRowIndex <= lastVisibleRow + m_AfterCacheCount);
                }
                else
                {
                    // 计算当前Item在第几列
                    int itemColIndex = Mathf.FloorToInt((position.x - m_Padding.left) / (m_CellWidth + m_Spacing));
                    if (itemColIndex < 0) itemColIndex = 0;
                    
                    // 计算可见区域的第一列和最后一列
                    float visibleLeftPos = visibleRect.xMin;
                    float visibleRightPos = visibleRect.xMax;
                    
                    int firstVisibleCol = Mathf.FloorToInt((visibleLeftPos - m_Padding.left) / (m_CellWidth + m_Spacing));
                    if (firstVisibleCol < 0) firstVisibleCol = 0;
                    
                    int lastVisibleCol = Mathf.FloorToInt((visibleRightPos - m_Padding.left) / (m_CellWidth + m_Spacing));
                    
                    // 基于缓存数量的可见性判断
                    return (itemColIndex >= firstVisibleCol - m_BeforeCacheCount) && 
                           (itemColIndex <= lastVisibleCol + m_AfterCacheCount);
                }
            }
            else
            {
                // 原始的距离模式
                if (m_Direction == e_Direction.Vertical)
                {
                    float itemTop = position.y;
                    float itemBottom = position.y - m_CellHeight;
                    
                    // 使用缓存变量减少重复计算
                    float topMargin = m_Spacing + m_CellHeight * 0.2f;
                    float bottomMargin = m_CellHeight * 1.5f;
                    
                    // 优化判断逻辑，减少比较操作
                    return (itemBottom + topMargin) < visibleRect.yMax && 
                           itemBottom > (visibleRect.yMin - bottomMargin);
                }
                else
                {
                    float itemLeft = position.x;
                    float itemRight = position.x + m_CellWidth;
                    
                    float leftMargin = m_Spacing + m_CellWidth * 0.2f;
                    float rightMargin = m_CellWidth * 1.5f;
                    
                    // 优化判断逻辑，减少比较操作
                    return (itemLeft - leftMargin) < visibleRect.xMax && 
                           itemRight > (visibleRect.xMin - rightMargin);
                }
            }
        }
    }
}

/*
============================ 增强版循环列表使用指南 ============================

【基本使用流程】
1. 获取组件
```lua
-- 获取或添加组件
local scrollViewObj = self.transform:Find("ScrollView").gameObject
local scrollView = scrollViewObj:GetComponent(typeof(CS.CircularScrollView.EnhancedUICircularScrollView))
if not scrollView then
    scrollView = scrollViewObj:AddComponent(typeof(CS.CircularScrollView.EnhancedUICircularScrollView))
end
```

2. 基础配置
```lua
-- 设置Cell模板（必须）
local cellTemplate = UIUtil.find_game_object(self.transform, "CellTemplate")
scrollView.m_CellGameObject = cellTemplate
cellTemplate:SetActive(false)  -- 模板必须设置为不可见

-- 基础配置
scrollView.m_Row = 1  -- 每行/列显示数量
scrollView.m_Spacing = CS.UnityEngine.Vector2(10, 10)  -- 项目间距
scrollView.m_Padding = CS.UnityEngine.RectOffset(15, 15, 10, 10)  -- 内边距
```

3. 性能优化配置（三选一）
```lua
-- 方案1: 极致缓存模式（适合项目较少的列表）
scrollView:SetExtremeCacheMode(true)

-- 方案2: 数量模式缓存（适合固定数量的列表）
scrollView:SetCacheCountMode(true, 1, 1)  -- 前后各缓存1行/列

-- 方案3: 距离模式缓存（适合不定数量的列表）
scrollView:SetDistanceCacheMode(100)  -- 设置缓存区域大小

-- 对象池配置（建议）
scrollView.m_PoolPreloadCount = 6  -- 预加载数量
scrollView:SetMaxPoolSize(8)  -- 对象池最大容量
```

4. 动画配置（可选）
```lua
-- 基础动画配置
scrollView.m_EnableItemAnimation = true  -- 启用动画
scrollView.m_OnlyAnimateFirstTime = true  -- 仅首次播放
scrollView.m_AnimationDuration = 0.3  -- 动画时长
scrollView.m_AnimationOffset = 0.05  -- 动画延迟

-- 自定义动画（可选）
local animParams = CS.CircularScrollView.AnimationManager.AnimationParams(
    CS.CircularScrollView.AnimationManager.AnimationType.Combined)
animParams.duration = 0.5
animParams.delay = 0.08
animParams.slideOffset = 150
scrollView:GetAnimationManager():SetDefaultParams(animParams)
```

5. 初始化与数据绑定
```lua
-- 初始化列表
scrollView:Init(function(cell, index)
    -- index从1开始
    local data = self.dataList[index]
    if not data then return end
    
    -- 获取组件
    local txtName = UIUtil.find_txt_component(cell.transform, "Name")
    local imgIcon = UIUtil.find_img_component(cell.transform, "Icon")
    local btnItem = UIUtil.find_game_object(cell.transform, "Button")
    
    -- 更新显示
    txtName.text = data.name
    framework.prop_util.show(imgIcon, data.icon)
    
    -- 绑定事件
    UIUtil.set_btn_click(btnItem, function()
        self:OnItemClick(data, index)
    end)
end)

-- 显示列表
scrollView:ShowList(#self.dataList)  -- 显示全部
-- 或者滚动到指定位置
scrollView:ShowList(#self.dataList, 5, 0.3)  -- 滚动到第5个，动画时间0.3秒
```

【常用接口说明】
1. 数据更新：
   * ShowList(itemCount, [scrollToIndex], [duration]) - 数量变化时使用
   * UpdateList() - 数量不变，内容变化时使用
   * UpdateCell(index) - 更新单个项目，index从1开始
   * ScrollToIndex(index, [duration]) - 滚动到指定位置

2. 缓存控制：
   * SetExtremeCacheMode(bool) - 极致缓存模式
   * SetCacheCountMode(bool, beforeCount, afterCount) - 数量模式缓存
   * SetDistanceCacheMode(float) - 距离模式缓存

3. 动画控制：
   * SetEnableItemAnimation(bool) - 启用/禁用动画
   * SetOnlyAnimateFirstTime(bool) - 设置是否仅首次播放
   * SetAnimationDuration(float) - 设置动画时长
   * SetAnimationOffset(float) - 设置动画延迟
   * ResetAnimationState() - 重置动画状态

4. 资源管理：
   * ClearAll() - 清除所有项目
   * DisposeAll() - 释放所有资源（销毁时调用）
   * SetMaxPoolSize(int) - 设置对象池容量

【注意事项】
1. 模板设置：
   - Cell模板必须设置为不可见(SetActive(false))
   - 不要直接修改m_CellGameObject对象

2. 性能优化：
   - 列表项回调中避免复杂计算
   - 滚动期间避免加载大量资源
   - 根据实际需求选择合适的缓存模式

3. 动画相关：
   - 动画不生效时检查m_EnableItemAnimation是否为true
   - 动画效果不明显时检查Duration和Offset值
   - 动画方向会根据滚动方向自动调整

4. 资源管理：
   - UI销毁时必须调用DisposeAll()
   - 避免在OnDestroy前反复调用ClearAll()和ShowList()
   - 合理设置对象池大小避免内存占用过大

5. 索引规则：
   - Init回调中的index参数从1开始
   * UpdateCell方法的index参数从1开始
   - 所有接口的索引参数都是从1开始

=======================================================================
*/
